//
//  CZHomeTableViewController.swift
//  czbkiosweibo5
//
//  Created by zhangping on 15/10/12.
//  Copyright © 2015年 zhangping. All rights reserved.
//

import UIKit
import AFNetworking
import SVProgressHUD

// 枚举,管理cell的重用标示
enum CZStatusCellIdentifier: String {
    case NormalCell = "NormalCell"
    case ForwardCell = "ForwardCell"
    
    /**
    根据模型返回对应的重用标示
    - parameter status: 微博模型
    - returns: 重用标示
    */
    static func cellId(status: CZStatus) -> String {
        // status.retweeted_status == nil 表示原创微博
        return (status.retweeted_status == nil) ? NormalCell.rawValue : ForwardCell.rawValue
    }
}

class CZHomeTableViewController: CZBaseTableViewController {
    
    // MARK: - 属性
    /// cell重用标示
//    private let cellIdentifier = "cellIdentifier"
    
    /// 微博模型数组
    var statuses: [CZStatus]? {
        didSet {
            tableView.reloadData()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        if CZUserAccount.loadAccount() == nil {
            return
        }
        
        // 设置导航栏
        setNavigationBar()
        
        prepareTableView()
        
        // 注册cell点击的通知
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "pictureSelected:", name: CZStatusPictureViewCellSelectedPictureNotification, object: nil)
        
        // 加载微博数据
//        loadStatus()
    }
    
    deinit {
        // 注销通知
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    /// cell点击后处理方法
    func pictureSelected(notification: NSNotification) {
//        print("控制器接收到通知: \(notification)")
        
        // 重通知里面获取传过来的参数
        guard let urls = notification.userInfo?[CZStatusPictureViewCellSelectedPictureURLKey] as? [NSURL] else {
            print("urls 为空")
            return
        }
        
        guard let indexPath = notification.userInfo?[CZStatusPictureViewCellSelectedPictureIndexPathKey] as? NSIndexPath else {
            print("indexPath 为空")
            return
        }
        
        // 弹出照片浏览控制器
        let controller = CZPhotoBrowserViewController(urls: urls, indexPath: indexPath)
        
        presentViewController(controller, animated: true, completion: nil)
    }
    
    // 准备tableView
    private func prepareTableView() {
        // 注册原创和转发cell
        tableView.registerClass(CZStatusNormalCell.self, forCellReuseIdentifier: CZStatusCellIdentifier.NormalCell.rawValue)
        tableView.registerClass(CZStatusForwardCell.self, forCellReuseIdentifier: CZStatusCellIdentifier.ForwardCell.rawValue)
        
//        tableView.rowHeight = 100
        // 设置预估行高, 使用预估行高,可以减少行高的计算次数,预估行高尽可能的准确
        tableView.estimatedRowHeight = 300
        // 自动计算行高
//        tableView.rowHeight = UITableViewAutomaticDimension
        
        // 去掉分割线
        tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        
        // 设置上拉加载数据菊花为tableView的footView
        tableView.tableFooterView = pullUpView
        
        // 测试 refreshControl, UIRefreshControl宽度默认是屏幕的宽度,高度是60
        refreshControl = CZRefreshControl()
        
        // 当用户刷新的时候会调用 ValueChanged 事件
        // 完成刷新的时候需要调用endRefreshing来结束刷新,否则,tableView不会自动退回去
        refreshControl?.addTarget(self, action: "loadStatus", forControlEvents: UIControlEvents.ValueChanged)
        
        // 调用 beginRefreshing 开始刷新数据,只会进入刷新状态,并不会触发 UIControlEvents.ValueChanged 事件
        refreshControl?.beginRefreshing()
        
        // 代码触发 UIControlEvents.ValueChanged
        refreshControl?.sendActionsForControlEvents(UIControlEvents.ValueChanged)
    }
    
    /**
    加载微博数据
    */
    @objc private func loadStatus() {
        print("开始加载微博数据")

        // 下拉刷新,获取最大的微博id赋值给since_id.
        // 当第一次进入程序,获取不到最大微博id,赋值0给since_id,加载最新20条微博数据
        var since_id = statuses?.first?.id ?? 0
        NSBundle.mainBundle()
        var max_id = 0
        
        // 菊花正在转,表示上拉加载数据
        if pullUpView.isAnimating() {
            // 清空 since_id
            since_id = 0
            
            // max_id = 当前最小的微博id
            max_id = statuses?.last?.id ?? 0
        }
        
        CZStatus.loadStatus(since_id, max_id: max_id) { (list, error) -> () in
            // 结束刷新
            self.refreshControl?.endRefreshing()
            
            // 数据加载完成,停止上拉加载数据的菊花
            self.pullUpView.stopAnimating()
            
            // 判断是否加载微博成功
            if error != nil {
                SVProgressHUD.showErrorWithStatus("加载微博数据出错", maskType: SVProgressHUDMaskType.Black)
                return
            }
            
            let count = list?.count ?? 0
            
            // 如果是下拉刷新显示加载了多少条微博
            if since_id > 0 {
                self.showPullDownTip(count)
            }
            
            if count == 0 {
                print("没有微博数据")
                return
            }
            
            // 如果是下拉刷新,将加载到的数据添加到现有数据的前面
            if since_id > 0 {
                print("下拉刷新: \(count)条微博")
                self.statuses = list! + self.statuses!
            } else if max_id > 0 {
                // 上拉加载更多数据,将加载到的数据拼接在现有数据的后面
                print("上拉加载: \(count)条微博")
                self.statuses = self.statuses! + list!
            } else {
                print("加载: \(count)条微博")
                // 将加载好的数据赋值给微博数组属性
                self.statuses = list
            }
        }
    }
    
    /**
    显示加载多少条数据.只在下拉刷新数据的时候调用
    - parameter count: 条数
    */
    private func showPullDownTip(count: Int) {

        tipLabel.text = count == 0 ? "没有微博数据" : "加载了 \(count) 条微博"
        
//        print("\(navigationController?.navigationBar)")
        
        // 记录动画起始frame
        let srcFrame = tipLabel.frame
        let duration = 0.75
        UIView.animateWithDuration(duration, animations: { () -> Void in
            self.tipLabel.frame.origin.y = self.navigationController!.navigationBar.frame.height
            }) { (_) -> Void in
                UIView.animateWithDuration(duration, delay: 0.3, options: UIViewAnimationOptions(rawValue: 0), animations: { () -> Void in
                    self.tipLabel.frame = srcFrame
                    }, completion: { (_) -> Void in

                })
        }
    }
    
    /*
        获取行高这个方法调用频繁,每次获取行高都需要获取到status,在获取缓存的cell,通过cell的rowHeight计算行高,是比较耗性能的.
        解决方案:每当计算好cell的行高后将其缓存起来,下次直接使用缓存好的行高
            1. 在 CZHomeTableViewController 增加一个字典,key为 indexPath, value为计算好的行高,需要维护字典,比较麻烦
            2. 在对应的status模型里面添加行高属性,当计算好行高后,将行高缓存到status模型里面
    */
    // MARK: - table 数据源和代理方法
    /// 返回每个cell的高度
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        // 获取status
        let status = statuses![indexPath.row]
        
        // 判断status里面是否有缓存的行高
        if let rowHeight = status.rowHeight {
//            print("返回缓存行高: \(rowHeight)")
            return rowHeight
        }
        
//        print("计算cell高度:\(indexPath)")
        
        // 获取 cell重用标示
        let cellId = CZStatusCellIdentifier.cellId(status)
        
        // 获取cell, 获取到的cell统一转成 CZStatusCell
        let cell = tableView.dequeueReusableCellWithIdentifier(cellId) as! CZStatusCell
        
        // 使用cell计算行高
        let rowHeight = cell.rowHeight(status)
        
        // 缓存计算好的行高
        status.rowHeight = rowHeight
        
        return rowHeight
    }
    
    /// 返回微博数量
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // ? 表示如果statuses有值才执行statuses.count
        // ?? statuses = nil 时返回 0
        return statuses?.count ?? 0
    }
    
    /// 返回微博cell
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let status = statuses![indexPath.row]
        
        // 获取 cell重用标示
        let cellId = CZStatusCellIdentifier.cellId(status)
        
        // 获取cell, 获取到的cell统一转成 CZStatusCell
        let cell = tableView.dequeueReusableCellWithIdentifier(cellId, forIndexPath: indexPath) as! CZStatusCell
        
        // 设置cell的微博模型
        cell.status = status
        
        // 如果是最后一个cell,并且上拉加载菊花没有动画,上拉加载更多数据
        if indexPath.row == statuses!.count - 1 && !pullUpView.isAnimating() {
            print("上拉加载数据")
            pullUpView.startAnimating()
            // 加载数据
            loadStatus()
        }

        return cell
    }
    
    // MARK: - 设置导航栏
    private func setNavigationBar() {
        // 设置导航栏左按钮
//        let leftButton = UIButton()
//        leftButton.setBackgroundImage(UIImage(named: "navigationbar_friendsearch"), forState: UIControlState.Normal)
//        leftButton.setBackgroundImage(UIImage(named: "navigationbar_friendsearch_highlighted"), forState: UIControlState.Highlighted)
//        leftButton.sizeToFit()
//        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: leftButton)
        // 设置导航栏右按钮
//        let rightButton = UIButton()
//        rightButton.setBackgroundImage(UIImage(named: "navigationbar_pop"), forState: UIControlState.Normal)
//        rightButton.setBackgroundImage(UIImage(named: "navigationbar_pop_highlighted"), forState: UIControlState.Highlighted)
//        rightButton.sizeToFit()
//        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: rightButton)
        
        // 设置导航栏左右按钮
//        navigationItem.leftBarButtonItem = createBarButtonItem("navigationbar_friendsearch", highlightedImageName: "navigationbar_friendsearch_highlighted")
        
        // 设置导航栏右按钮
//        navigationItem.rightBarButtonItem = createBarButtonItem("navigationbar_pop", highlightedImageName: "navigationbar_pop_highlighted")
        
//        // 设置导航栏左右按钮
//        navigationItem.leftBarButtonItem = UIBarButtonItem.createBarButtonItem("navigationbar_friendsearch", highlightedImageName: "navigationbar_friendsearch_highlighted")
//        
//        // 设置导航栏右按钮
//        navigationItem.rightBarButtonItem = UIBarButtonItem.createBarButtonItem("navigationbar_pop", highlightedImageName: "navigationbar_pop_highlighted")
        
        // 设置导航栏左右按钮
        navigationItem.leftBarButtonItem = UIBarButtonItem(imageName: "navigationbar_friendsearch", highlightedImageName: "navigationbar_friendsearch_highlighted")
        
        // 设置导航栏右按钮
        navigationItem.rightBarButtonItem = UIBarButtonItem(imageName: "navigationbar_pop", highlightedImageName: "navigationbar_pop_highlighted")
        
        // 设置导航栏标题
//        let button = CZHomeTitleView()
//        button.setTitle("传智ios ", forState: UIControlState.Normal)
//        button.setImage(UIImage(named: "navigationbar_arrow_down"), forState: UIControlState.Normal)
//        button.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
//        button.sizeToFit()
//        navigationItem.titleView = button
        
        // 设置导航栏标题
        let button = CZHomeTitleView(title: "传智ios ")
        navigationItem.titleView = button
        
        // 添加点击事件
        button.addTarget(self, action: "homeTitleClick:", forControlEvents: UIControlEvents.TouchUpInside)
    }

    // 按钮点击事件,改变按钮箭头方向
    @objc private func homeTitleClick(button: UIButton) {
        // 改变按钮的状态
        button.selected = !button.selected
        
//        // 根据不同状态设置箭头旋转角度
//        var transform: CGAffineTransform = CGAffineTransformIdentity
//        // 选中状态,旋转180°,使箭头朝上
//        if button.selected {
//            UIView.animateWithDuration(0.25, animations: { () -> Void in
//                button.imageView?.transform = CGAffineTransformMakeRotation(CGFloat(M_PI))
//            })
//        } else {
//            // 未选中状态,旋转角度为0°,箭头朝下
//            UIView.animateWithDuration(0.25, animations: { () -> Void in
//                button.imageView?.transform = CGAffineTransformIdentity
//            })
//        }
        
        // 根据不同状态设置箭头旋转角度
        var transform: CGAffineTransform = CGAffineTransformIdentity
        // 选中状态,旋转180°,使箭头朝上
        if button.selected {
            /*
                UIView旋转动画的特点:
                    1.就近原则,如果需要旋转 270°, 360 - 270 = 90, 它会就近旋转90
                    2.两边一样远,就顺时针
            */
            transform = CGAffineTransformMakeRotation(CGFloat(M_PI - 0.01))
        } else {
            // 未选中状态,旋转角度为0°,箭头朝下
            transform = CGAffineTransformIdentity
        }
        
        // 动画
        UIView.animateWithDuration(0.25, animations: { () -> Void in
            button.imageView?.transform = transform
        })
        
        // 创建Popover中的controller,并modal出来
        let controller = UIStoryboard.init(name: "Popover", bundle: nil).instantiateViewControllerWithIdentifier("PopoverController")
        
        // 要实现自定义转场
        // 1.需要实现转场协议
        controller.transitioningDelegate = self
        
        // 1.设置转场样式
        controller.modalPresentationStyle = UIModalPresentationStyle.Custom
        
        presentViewController(controller, animated: true, completion: nil)
    }
    
    // MARK: - 懒加载
    // 上拉加载更多的进度视图
    private lazy var pullUpView: UIActivityIndicatorView = {
        // 根据样式创建
        let indicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
        
        // 设置颜色
        indicator.color = UIColor.grayColor()
        
        return indicator
    }()
    
    /// 下拉刷新提示view
    private lazy var tipLabel: UILabel = {
        let tipLabelHeight: CGFloat = 44
        
        let tipLabel = UILabel(frame: CGRectMake(0, -20 - tipLabelHeight, UIScreen.width, tipLabelHeight))
        tipLabel.backgroundColor = UIColor.orangeColor()
        tipLabel.textColor = UIColor.whiteColor()
        tipLabel.font = UIFont.systemFontOfSize(16)
        tipLabel.textAlignment = NSTextAlignment.Center
        
        // 导航栏的frame = (0 20; 375 44)
        self.navigationController?.navigationBar.insertSubview(tipLabel, atIndex: 0)
        
        return tipLabel
    }()

    /*
    /**
    快速创建带高亮图片的BarButton
    - parameter imageName:            正常时的图片名称
    - parameter highlightedImageName: 高亮时的图片名称
    - returns: UIBarButtonItem
    */
    private func createBarButtonItem(imageName: String, highlightedImageName: String) -> UIBarButtonItem {
        let button = UIButton()
    
        button.setBackgroundImage(UIImage(named: imageName), forState: UIControlState.Normal)
        button.setBackgroundImage(UIImage(named: highlightedImageName), forState: UIControlState.Highlighted)
        button.sizeToFit()
    
        return UIBarButtonItem(customView: button)
    }*/

    // TODO: 测试加载账户信息
//    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//        print(CZUserAccount.loadAccount())
//    }
}

// MARK: - 实现 transitioningDelegate 转场协议
extension CZHomeTableViewController: UIViewControllerTransitioningDelegate {
    
    // 返回一个负责展现的对象
    func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController? {
        return CZPopoverPresentationController(presentedViewController: presented, presentingViewController: presenting)
    }
    
    // 返回 控制 modal 出来时的动画 对象
    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CZPopover()
    }
    
    // 返回 控制 dismiss 的动画 对象
    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CZDismiss()
    }
}

// MARK: - 控制 dismiss 出来时的动画 对象
class CZDismiss: NSObject, UIViewControllerAnimatedTransitioning {
    
    // 返回动画时长
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
        return 0.25
    }
    
    // 控制动画方法
    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        // 将 modal 出来的控制器的 view 缩放到 (x: 1, y: 0)

        // 获取modal后的view
        let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!

        // 添加动画
        UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () -> Void in
            fromView.transform = CGAffineTransformMakeScale(1, 0.01)
            }) { (_) -> Void in
                // 转场动画完成后需要调用 completeTransition
                transitionContext.completeTransition(true)
        }
    }
}

// MARK: - 控制 modal 出来时的动画 对象
/*
    注意:
        1.一个对象不能光实现协议, 最起码需要继承NSObject
        2.返回这个对象后需要自己来添加视图
*/
class CZPopover: NSObject, UIViewControllerAnimatedTransitioning {
    
    // 返回动画时长
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
        return 0.5
    }
    
    /* 
        transitionContext: 提供转场需要的元素
            containerView: 容器视图
            viewForKey: 获取对应的view
                UITransitionContextFromViewKey: modal前控制器的view
                UITransitionContextToViewKey: modal后控制器的view
    
            viewControllerForKey: 获取对应的控制器
                UITransitionContextFromViewControllerKey: modal前控制器
                UITransitionContextToViewControllerKey： modal后控制器
    
            completeTransition: 完成转场需要调用
    */
    // 控制动画方法
    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        // 获取modal后的view
        let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
        
        // 添加到容器视图
        transitionContext.containerView()?.addSubview(toView)
        
        // 设置动画起始状态
        toView.transform = CGAffineTransformMakeScale(1, 0)
        toView.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
        
        // 添加动画
        UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 3, options: UIViewAnimationOptions(rawValue: 0), animations: { () -> Void in
            toView.transform = CGAffineTransformIdentity
            }) { (_) -> Void in
                // 转场动画完成后需要调用 completeTransition
                transitionContext.completeTransition(true)
        }
    }
}

/*
    containerView: 转场的容器视图,modal出来的控制器的view需要称为它的subView
    presentedView: modal出来的控制器的view
    presentedViewController: modal出来的控制器
*/

// MARK: - 负责展现
class CZPopoverPresentationController: UIPresentationController {
    
    // 将要开始转场
    override func presentationTransitionWillBegin() {
        // 设置转场动画容器视图的背景
        containerView?.backgroundColor = UIColor(white: 0, alpha: 0.2)
        
        // 创建点击手势
        let top = UITapGestureRecognizer(target: self, action: "close")
        
        // 添加点击手势
        containerView?.addGestureRecognizer(top)
    }
    
    // 将要开始布局转场视图
    override func containerViewWillLayoutSubviews() {
        super.containerViewWillLayoutSubviews()
        
        // 设置modal出来控制器view的大小
        presentedView()?.frame = CGRect(x: 100, y: 56, width: 200, height: 260)
    }
    
    // 关闭Modal出来的控制器
    func close() {
        presentedViewController.dismissViewControllerAnimated(true, completion: nil)
    }
}